/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * NewJFrame.java
 *
 * Created on Nov 5, 2010, 4:27:56 PM
 */

package preka;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.Timer;
import prefuse.Display;
import prefuse.Visualization;
import prefuse.controls.PanControl;
import prefuse.controls.ZoomControl;
import prefuse.data.CascadedTable;
import prefuse.data.Edge;
import prefuse.data.Graph;
import prefuse.data.Table;
import prefuse.data.tuple.TupleSet;
import prefuse.util.ColorLib;
import prefuse.util.force.Force;
import prefuse.util.force.ForceItem;
import prefuse.util.force.ForceSimulator;
import prefuse.util.ui.UILib;
import prefuse.visual.EdgeItem;
import prefuse.visual.VisualItem;
import preka.prefuse.action.layout.graph.IVCForceDirectedLayout;
import preka.prefuse.controls.IVCDragControl;
import preka.prefuse.visual.VisualInstances;
import preka.util.CSVWriter;
import preka.util.DateUtils;
import weka.clusterers.InstancePair;

/**
 *
 * @author vhbarros
 */
public class NewJFrame extends javax.swing.JFrame {

    private IVC m_ivc;
    private Timer m_timer;
    private int m_numInstancesMoved, m_iteraction, m_currRun, m_numRuns;
    private CSVWriter m_file;

    /** Creates new form NewJFrame */
    public NewJFrame() {

        // Inicializações para construção de UI
        UILib.setPlatformLookAndFeel();
        initComponents();

        // Outras inicializações
        m_currRun = 1;
        jTFCurrentRun.setText(String.valueOf(m_currRun));

        // "Loop" do IVC
        // TODO Melhoria: Substituição de loop na camada UI por Actions na visualização na camada lógica
        int delay = 100; //IVC.DEFAULT_STEP_TIME;
        ActionListener taskPerformer = new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                try {

                    int newNumInstancesMoved = 0;
                    if(m_ivc != null)
                        newNumInstancesMoved = m_ivc.getNumMovedInstances();

                    System.out.println("tick moves:"+newNumInstancesMoved);
                    if(jCBRestart.isSelected() && newNumInstancesMoved >= 2 && jCBUserSimulation.getSelectedIndex() != 0)
                        if(!m_ivc.isAlive()) {
                            m_file.writeLine("Erro!", "Erro!", "Erro!");
                            loadIVC();
                        }

                    if (//m_ivc.getStatus() == IVC.RUNNING &&             // O "motor" do IVC tem de estar a ser executado
                        newNumInstancesMoved > m_numInstancesMoved &&   // Têm de existir novas movimentações
                        newNumInstancesMoved >= 2)                      // Na 1ª iteracção têm de ser movidas duas instâncias
                    {


                        // Parar tempo para realizar acções
                        m_timer.stop();
                        
                        // Parar visualização
                        // TODO parar visualização + loading...
                        
                        m_numInstancesMoved = m_ivc.getNumMovedInstances();
                        m_iteraction++;
                        printLogLn("---------------------------------------");
                        printLogLn(m_iteraction+"ª iteracção: "+m_numInstancesMoved+" nós movidos:");


                        // Processar restrições
                        printLogLn(" - A processar restrições:");
                        ArrayList a = m_ivc.processConstraints();
                        /*Iterator it = a.iterator();
                        while (it.hasNext()){
                            InstancePair ip = (InstancePair) it.next();
                            System.out.println(" --- 1º:"+ip.first+" 2º:"+ip.second+" rest:"+ip.linkType);
                        }*/


                        // Executar agrupamento de dados
                        printLogLn(" - A executar o agrupamento de dados...");
                        m_ivc.runClusterer(a);


                        // Confirmar ARI
                        printLogLn(" --- ARI: "+Double.toString(m_ivc.randIndex()));
                        jTFPercARI.setText(Double.toString(m_ivc.randIndex()*100));
                        jTFNumNodesMoved.setText(String.valueOf(m_numInstancesMoved));
                        double perc = (double)m_numInstancesMoved/150*100;
                        jTFPercNodesMoved.setText(String.valueOf(perc));

                        // Escreve no ficheiro de resultados
                        m_file.writeLine(String.valueOf(m_currRun), String.valueOf(m_numInstancesMoved), Double.toString(m_ivc.randIndex()));

                        if(m_ivc.randIndex() == 1.0d) {
                            printLogLn(" - Final da "+m_currRun+"ª execução!");
                            System.out.println("************ Final "+m_currRun+"ª execução ("+DateUtils.now()+") ************");
                            m_currRun++;
                            jTFCurrentRun.setText(String.valueOf(m_currRun));
                            
                            // Se atingiu o número de execuções termina
                            if (m_currRun > m_numRuns) { System.out.println("acabou!!");
                                m_file.closeFile();
                                m_ivc.stopVisualization();
                                m_timer.stop();
                                System.exit(0);
                            // Senão reinicia o processo
                            } else {
                                loadIVC();
                            }
                        }
                        else {

                            // Reiniciar Visualização
                            printLogLn(" - A recarregar visualização...");
                            m_ivc.reloadGraph();
                            /*m_ivc.loadGraph(file);

                            m_ivc.createLayout();
                            m_ivc.registerActionListLayout();

                            m_ivc.reloadVisualization();*/
                            printLogLn(" - Visualização carregada com sucesso!");

                            // Reiniciar tempo
                            m_timer.start();
                            //jTextArea1.setText(jTextArea1.getText()+"\n andou!");
                        }
                    }

                } catch (Exception ex) {
                    Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        };
        m_timer = new Timer(delay, taskPerformer);
        m_timer.start();
    }

    private void printLogLn (String line) {
        jTextField1.setText(line);
    }

    private void loadIVC() {

        System.out.println("************ Início "+m_currRun+"ª execução ("+DateUtils.now()+") ************");
        // Para o loop principal para efectuar as acções de carregamento do IVC
        if (m_timer != null)
            m_timer.stop();

        // Reset do sistema (viva o garbage collector!! :) )
        m_ivc = null;
        m_numInstancesMoved = 0;
        m_iteraction = 0;

        // Conjunto de dados
        String dataset = getSelectedDataSetName();
        //final String file = "/home/joaoduarte/Dropbox/Tese/Software/preka/data/"+dataset+".arff";
        final String file = "/home/vhbarros/Dropbox/Tese/Software/preka/data/"+dataset+".arff";
        //final String file = "C:\\Users\\vhbarros\\Desktop\\My Dropbox\\Tese\\Software\\preka\\data\\"+dataset+".arff";

        // 0. Início do método IVC
        //m_ivc = new IVC(IVC.MPCKMEANS, IVC.FORCE_DIRECTED, IVC.NEAREST_NEIGHBOUR, IVC.FARTHEST_FIRST);
        System.out.println("Clustering:"+jCBClustering.getSelectedIndex()+
                           " Layout:"+jCBLayout.getSelectedIndex()+
                           " Relacionais:"+jCBRelationalData.getSelectedIndex()+
                           " Utilizador:"+jCBUserSimulation.getSelectedIndex());
        m_ivc = new IVC(jCBClustering.getSelectedIndex(),       // Algoritmo Clustering
                        jCBLayout.getSelectedIndex(),           // Layout
                        jCBRelationalData.getSelectedIndex(),   // Heurística Ligações Relacionais
                        jCBUserSimulation.getSelectedIndex());  // Heurística Simulação Utilizador

        try {
            // 1. Criação da visualização inicial
            m_ivc.loadGraph(file);
        } catch (Exception ex) {
            Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
        }
        m_ivc.createVisualization();
        m_ivc.createDisplay(800, 800);

        jSplitPane2.setLeftComponent(m_ivc.getDisplay());
        jSplitPane2.setDividerLocation(800);

        m_ivc.createClusterer();

        if (m_timer != null) {
            m_ivc.runVisualization();
            m_timer.start();
        }
    }

    // TODO: Carregar a partir de ficheiro + tornar isto dinâmico!!
    private String getSelectedDataSetName() {
        switch (jCBDataSet.getSelectedIndex()) {
            case 0:
                return "circles";
            case 1:
                return "overlappingcircles";
            case 2:
                return "iris";
            case 3:
                return "cigar";
            case 4:
                return "halfrings";
            default:
                break;
        }
        return "none";
    }



    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jButton1 = new javax.swing.JButton();
        jTabbedPane1 = new javax.swing.JTabbedPane();
        jSplitPane1 = new javax.swing.JSplitPane();
        jSplitPane2 = new javax.swing.JSplitPane();
        jPanel1 = new javax.swing.JPanel();
        jButton2 = new javax.swing.JButton();
        jCBDataSet = new javax.swing.JComboBox();
        jButton3 = new javax.swing.JButton();
        jLabel1 = new javax.swing.JLabel();
        jTFPercARI = new javax.swing.JTextField();
        jTFPercNodesMoved = new javax.swing.JTextField();
        jLabel2 = new javax.swing.JLabel();
        jTFNumNodesMoved = new javax.swing.JTextField();
        jLabel3 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        jCheckBox2 = new javax.swing.JCheckBox();
        jCheckBox1 = new javax.swing.JCheckBox();
        jCheckBox3 = new javax.swing.JCheckBox();
        jLabel6 = new javax.swing.JLabel();
        jLabel7 = new javax.swing.JLabel();
        jCBLayout = new javax.swing.JComboBox();
        jLabel8 = new javax.swing.JLabel();
        jLabel9 = new javax.swing.JLabel();
        jCBRelationalData = new javax.swing.JComboBox();
        jCBClustering = new javax.swing.JComboBox();
        jLabel10 = new javax.swing.JLabel();
        jLabel11 = new javax.swing.JLabel();
        jCBUserSimulation = new javax.swing.JComboBox();
        jLabel12 = new javax.swing.JLabel();
        jSNumRuns = new javax.swing.JSpinner();
        jLabel13 = new javax.swing.JLabel();
        jTFCurrentRun = new javax.swing.JTextField();
        jCBPreset = new javax.swing.JComboBox();
        jLabel14 = new javax.swing.JLabel();
        jCBRestart = new javax.swing.JCheckBox();
        jLabel15 = new javax.swing.JLabel();
        jTextField1 = new javax.swing.JTextField();
        jTabbedPane2 = new javax.swing.JTabbedPane();
        jMenuBar1 = new javax.swing.JMenuBar();
        jMenu1 = new javax.swing.JMenu();
        jMenu2 = new javax.swing.JMenu();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Preka - Interactive Visual Clustering");

        jButton1.setText("Close");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jSplitPane1.setDividerLocation(800);
        jSplitPane1.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);

        jSplitPane2.setDividerLocation(800);

        jButton2.setText("Stop");
        jButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton2ActionPerformed(evt);
            }
        });

        jCBDataSet.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Circles", "Overlapping Circles", "Iris", "Cigar", "HalfRings" }));
        jCBDataSet.setSelectedIndex(2);

        jButton3.setLabel("Start");
        jButton3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton3ActionPerformed(evt);
            }
        });

        jLabel1.setText("% ARI:");

        jTFPercARI.setEditable(false);
        jTFPercARI.setHorizontalAlignment(javax.swing.JTextField.TRAILING);

        jTFPercNodesMoved.setEditable(false);
        jTFPercNodesMoved.setHorizontalAlignment(javax.swing.JTextField.TRAILING);

        jLabel2.setText("% Nodes Moved:");

        jTFNumNodesMoved.setEditable(false);
        jTFNumNodesMoved.setHorizontalAlignment(javax.swing.JTextField.TRAILING);

        jLabel3.setText("# Nodes Moved:");

        jLabel4.setFont(new java.awt.Font("Tahoma", 1, 11));
        jLabel4.setText("Statistics:");

        jLabel5.setFont(new java.awt.Font("Tahoma", 1, 11));
        jLabel5.setText("Dataset options:");

        jCheckBox2.setText("Show Relational Edges");

        jCheckBox1.setText("Show Clustering Edges");
        jCheckBox1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jCheckBox1ActionPerformed(evt);
            }
        });

        jCheckBox3.setText("Show Cluster Centers");

        jLabel6.setFont(new java.awt.Font("Tahoma", 1, 11));
        jLabel6.setText("View:");

        jLabel7.setText("Dataset:");

        jCBLayout.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "No Layout", "Force Directed" }));
        jCBLayout.setSelectedIndex(1);

        jLabel8.setText("Layout:");

        jLabel9.setText("Relational Data:");

        jCBRelationalData.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "No Relational Data", "Nearest Neighbour" }));
        jCBRelationalData.setSelectedIndex(1);

        jCBClustering.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "No Clustering", "MPCK-Means" }));
        jCBClustering.setSelectedIndex(1);

        jLabel10.setText("Clustering:");

        jLabel11.setText("User Simulation:");

        jCBUserSimulation.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Manual", "Farthest First", "Random" }));
        jCBUserSimulation.setSelectedIndex(1);

        jLabel12.setText("# Runs:");

        jSNumRuns.setValue(1);

        jLabel13.setText("Current Run:");

        jTFCurrentRun.setEditable(false);
        jTFCurrentRun.setHorizontalAlignment(javax.swing.JTextField.TRAILING);

        jCBPreset.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "IVC", "Clustering", "Layout FF", "Layout Baseline", "Manual Baseline" }));
        jCBPreset.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jCBPresetActionPerformed(evt);
            }
        });

        jLabel14.setText("Preset:");

        jCBRestart.setSelected(true);
        jCBRestart.setText("Restart on error");

        jLabel15.setFont(new java.awt.Font("Tahoma", 1, 11));
        jLabel15.setText("Method options:");

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jCheckBox2)
                    .addComponent(jCheckBox1)
                    .addComponent(jCheckBox3)
                    .addComponent(jLabel6)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(jLabel5)
                        .addGap(94, 94, 94))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel3)
                            .addComponent(jLabel2)
                            .addComponent(jLabel1)
                            .addComponent(jLabel13))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 40, Short.MAX_VALUE)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(jTFCurrentRun)
                            .addComponent(jTFPercARI)
                            .addComponent(jTFPercNodesMoved)
                            .addComponent(jTFNumNodesMoved, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 126, Short.MAX_VALUE)))
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(jLabel4)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 81, Short.MAX_VALUE)
                        .addComponent(jCBRestart))
                    .addComponent(jLabel15)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                        .addComponent(jButton3)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButton2))
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel7)
                            .addComponent(jLabel9)
                            .addComponent(jLabel8)
                            .addComponent(jLabel10)
                            .addComponent(jLabel14)
                            .addComponent(jLabel11)
                            .addComponent(jLabel12))
                        .addGap(17, 17, 17)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                                .addGap(77, 77, 77)
                                .addComponent(jSNumRuns, javax.swing.GroupLayout.DEFAULT_SIZE, 76, Short.MAX_VALUE))
                            .addComponent(jCBUserSimulation, javax.swing.GroupLayout.Alignment.TRAILING, 0, 153, Short.MAX_VALUE)
                            .addComponent(jCBClustering, 0, 153, Short.MAX_VALUE)
                            .addComponent(jCBLayout, 0, 153, Short.MAX_VALUE)
                            .addComponent(jCBPreset, javax.swing.GroupLayout.Alignment.TRAILING, 0, 153, Short.MAX_VALUE)
                            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                .addComponent(jCBRelationalData, 0, 0, Short.MAX_VALUE)
                                .addComponent(jCBDataSet, 0, 153, Short.MAX_VALUE)))))
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel5)
                .addGap(14, 14, 14)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jCBDataSet, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel7))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jCBRelationalData, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel9))
                .addGap(12, 12, 12)
                .addComponent(jLabel15)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jCBPreset, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel14))
                .addGap(5, 5, 5)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jCBLayout, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel8))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jCBClustering, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel10))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jCBUserSimulation, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel11))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel12)
                    .addComponent(jSNumRuns, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButton2)
                    .addComponent(jButton3))
                .addGap(21, 21, 21)
                .addComponent(jLabel6)
                .addGap(18, 18, 18)
                .addComponent(jCheckBox2)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jCheckBox1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jCheckBox3)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 134, Short.MAX_VALUE)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel4)
                    .addComponent(jCBRestart))
                .addGap(18, 18, 18)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jTFCurrentRun, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel13))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jTFNumNodesMoved, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel3))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jTFPercNodesMoved, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel2))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jTFPercARI, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel1))
                .addContainerGap())
        );

        jSplitPane2.setRightComponent(jPanel1);

        jSplitPane1.setTopComponent(jSplitPane2);

        jTextField1.setEditable(false);
        jTextField1.setEnabled(false);
        jSplitPane1.setRightComponent(jTextField1);

        jTabbedPane1.addTab("Dataset Control", jSplitPane1);
        jTabbedPane1.addTab("Results", jTabbedPane2);

        jMenu1.setText("File");
        jMenuBar1.add(jMenu1);

        jMenu2.setText("Help");
        jMenuBar1.add(jMenu2);

        setJMenuBar(jMenuBar1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jButton1, javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jTabbedPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 1119, Short.MAX_VALUE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jTabbedPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 862, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jButton1)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed

        m_timer.stop();
        m_ivc.stopVisualization();

        //System.out.println("Width: "+m_ivc.getDisplay().getWidth()+" Height: "+m_ivc.getDisplay().getHeight());

        /*VisualItem vi = m_ivc.getVisualization().getVisualItem(IVC.NODES_GROUP, m_ivc.getNodeByInstanceAttr(-3));
        //System.out.println("Bounds: "+vi.getBounds().toString());
        vi.setFixed(true);
        vi.setInteractive(false);
        vi.setStartX(vi.getX());
        vi.setStartY(vi.getY());
        vi.setEndX(-200);
        vi.setEndY(-200);
        //m_ivc.getVisualInstances().getVisualInstance(14).setIsMoving(true);
        m_ivc.getVisualization().run("animator");*/

        //VisualInstances vi = m_ivc.getVisualInstances();

        //vi.updatePositions(m_ivc.getVisualization(), IVC.NODES_GROUP);
        //vi.printVisualInstances();

        /*ArrayList a = m_ivc.getIVCDragControl().getMovedInstances();
        Iterator it = a.iterator();
        while (it.hasNext())
        {
            VisualItem vi = (VisualItem) it.next();
            // System.out.println("movido:"+vi.getRow()+" X:"+vi.getX()+" Y:"+vi.getY());
            printLogLn("movido:"+vi.getRow()+" X:"+vi.getX()+" Y:"+vi.getY());
        }*/


        /*if (m_ivc.getVisualization().getAction("layout").isRunning())
            System.out.println("Está a correr...");
        else
            System.out.println("Parou!");*/

        /*Iterator items = m_ivc.getVisualization().items("graph.nodes");
        while (items.hasNext()) {
            VisualItem i = (VisualItem) items.next();
            System.out.println("item: "+ i.getRow() + " "+
                               i.getSourceTuple().getColumnName(0)+":"+i.getSourceTuple().getInt(IVC.INSTANCE_ATTRIBUTE) +
                               " x:"+i.getX() +
                               " y:"+i.getY());
        }*/

        /*ForceSimulator fsim = m_ivc.getLayout().getForceSimulator();

        // Forças utilizadas no layout
        Force [] f = fsim.getForces();
        for (int i = 0; i < f.length; i++) {
            String tipo = f[i].isItemForce() ? "nó":"arco";
            System.out.println("Força: "+tipo);
            for (int j = 0; j < f[i].getParameterCount() ; j++)
                System.out.println("   --- "+f[i].getParameterName(j)+": "+f[i].getParameter(j));
        }
        

        Iterator fi = fsim.getItems();
        while (fi.hasNext()) {
            ForceItem fitem = (ForceItem) fi.next();
            System.out.println("Força: "+fitem.toString());
        }*/


        /*Iterator items = m_ivc.getVisualization().items("graph.nodes");
        while (items.hasNext()) {
            VisualItem i = (VisualItem) items.next();
            //ForceItem fi = (ForceItem) i.get("_forceitem");
            //EdgeItem e = (EdgeItem) i;
            //System.out.println(" - Source: "+e.getSourceItem().getString(IVC.INSTANCE_ATTRIBUTE)+" Dest: "+ e.getTargetItem().getString(IVC.INSTANCE_ATTRIBUTE)+" Force:"+fi.toString());
            
            if (i.getInt(IVC.INSTANCE_ATTRIBUTE) == -3) {
                System.out.println(i.getInt(IVC.INSTANCE_ATTRIBUTE)+" invalidado");
                i.setValidated(false);
            }
        }*/

        //m_ivc.getVisualization().run("color");

        

    }//GEN-LAST:event_jButton2ActionPerformed

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        System.exit(0);
    }//GEN-LAST:event_jButton1ActionPerformed

    private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton3ActionPerformed

        // Carrega a estrutura IVC
        loadIVC();
        m_numRuns = Integer.parseInt(jSNumRuns.getValue().toString());
        m_file = null;
        //final String filecsv = "/home/joaoduarte/Dropbox/Tese/Software/preka/out/"+
        final String filecsv = "/home/vhbarros/Dropbox/Tese/Software/preka/out/"+
        //final String filecsv = "C:\\Users\\vhbarros\\Desktop\\My Dropbox\\Tese\\Software\\preka\\out\\"+
                               getSelectedDataSetName()+"_"+
                               DateUtils.now()+"_"+
                               jSNumRuns.getValue().toString()+"_"+
                               jCBClustering.getSelectedIndex()+""+
                               jCBLayout.getSelectedIndex()+""+
                               jCBRelationalData.getSelectedIndex()+""+
                               jCBUserSimulation.getSelectedIndex()+".csv";
        try {
            m_file = new CSVWriter(filecsv);
        } catch (FileNotFoundException ex) {
            Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
        }


        m_ivc.runVisualization();
        //m_ivc.printVisualClusterMapping();

        //m_ivc.getVisualInstances().printVisualInstances();

        /*VisualItem vi = m_ivc.getVisualization().getVisualItem(IVC.NODES_GROUP, m_ivc.getNodeByInstanceAttr(1));
        vi.setFixed(true);
        vi.setInteractive(false);
        vi.setStartX(vi.getX());
        vi.setStartY(vi.getY());
        vi.setEndX(200);
        vi.setEndY(200);
        m_ivc.getVisualInstances().getVisualInstance(1).setIsMoving(true);
        m_ivc.getVisualization().run("animator");*/

        //m_ivc.reloadGraph();

        /*Graph g = (Graph) m_ivc.getVisualization().getGroup("graph");
        //Graph g2 = new Graph(g.getNodeTable(), g.getEdgeTable(), false);
        Iterator edges = g.edges();
        while (edges.hasNext()) {
            Edge e = (Edge) edges.next();

            System.out.println(" --- Arco: Tipo: "+e.getString(IVC.EDGE_TYPE_ATTRIBUTE)+
                               " Origem - "+e.getSourceNode().getInt(IVC.INSTANCE_ATTRIBUTE)+"("+e.getSourceNode().getRow()+")"+
                               " Destino - "+e.getTargetNode().getInt(IVC.INSTANCE_ATTRIBUTE)+"("+e.getTargetNode().getRow()+")");

            if (e.getString(IVC.EDGE_TYPE_ATTRIBUTE).equals(IVC.EDGE_CLUSTERING)
                && e.getTargetNode().getInt(IVC.INSTANCE_ATTRIBUTE) == 0
                ) {
                CascadedTable t = (CascadedTable) g.getEdgeTable();


                //t.getParentTable().removeRow(e.getRow());

                //long key2 = g.getKey(5);
                //t.getParentTable().setInt(e.getRow(), g.getEdgeTargetField(), (int)key2);

                //System.out.println(" --- Tipo: "+t.getParentTable().getString(e.getRow(), IVC.EDGE_TYPE_ATTRIBUTE));

                //t.removeRow(e.getRow());
                if(g.removeEdge(e))
                    System.out.println("Arco removido!");

                //m_ivc.getVisualization().removeGroup("graph");
                //m_ivc.getVisualization().addGraph("graph", g2);
            }

            //i.setFixed(true);
            //i.setX(50);
            //i.setY(50);
        }

        // Adicionar arco
        /*long key1 = g.getKey(3);
        long key2 = g.getKey(4);
        CascadedTable ct = (CascadedTable) g.getEdgeTable();
        Table te = ct.getParentTable();
        int r = te.addRow();

        te.setInt(r, g.getEdgeSourceField(), (int)key1);
        te.setInt(r, g.getEdgeTargetField(), (int)key2);
        te.setString(r, IVC.EDGE_TYPE_ATTRIBUTE, IVC.EDGE_CLUSTERING);
        VisualItem vi = m_ivc.getVisualization().getVisualItem(IVC.NODES_GROUP, g.getNode(r));
        if (vi.isVisible())
            System.out.println("Visível!");
        else
            System.out.println("Não Visível!");*/

        //g.addEdge(3, 4);*/


        /*m_ivc.runVisualization();

        Iterator it = m_ivc.getConstraints().iterator();
        while (it.hasNext()) {
            InstancePair ip = (InstancePair) it.next();
            System.out.println(" restrição - inst1:"+ip.first+" inst2:"+ip.second+" tipo:"+ip.linkType);
        }*/


        
    }//GEN-LAST:event_jButton3ActionPerformed

    private void jCheckBox1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBox1ActionPerformed
        // TODO add your handling code here:

        if (jCheckBox1.isSelected())
            System.out.println("seleccionado");
        else
            System.out.println("deseleccionado");
    }//GEN-LAST:event_jCheckBox1ActionPerformed

    private void jCBPresetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCBPresetActionPerformed
        switch (jCBPreset.getSelectedIndex()) {
            case 0: //IVC
                jCBLayout.setSelectedIndex(1); // Force Directed Layout
                jCBClustering.setSelectedIndex(1); // MPCK-Means
                jCBUserSimulation.setSelectedIndex(1); // Farthest First
                jCBRelationalData.setSelectedIndex(1); // Nearest Neighbour
                break;
            case 1: //Clustering
                jCBLayout.setSelectedIndex(1); // Force Directed Layout
                jCBClustering.setSelectedIndex(1); // MPCK-Means
                jCBUserSimulation.setSelectedIndex(2); // Random
                jCBRelationalData.setSelectedIndex(0); // No Relational Data
                break;
            case 2: //Layout FF
                jCBLayout.setSelectedIndex(1); // Force Directed Layout
                jCBClustering.setSelectedIndex(0); // No Clustering
                jCBUserSimulation.setSelectedIndex(1); // Farthest First
                jCBRelationalData.setSelectedIndex(1); // Nearest Neighbour
                break;
            case 3: //Layout Baseline
                jCBLayout.setSelectedIndex(1); // Force Directed Layout
                jCBClustering.setSelectedIndex(0); // No Clustering
                jCBUserSimulation.setSelectedIndex(2); // Random
                jCBRelationalData.setSelectedIndex(1); // Nearest Neighbour
                break;
            case 4: //Manual Baseline
                jCBLayout.setSelectedIndex(0); // No Layout
                jCBClustering.setSelectedIndex(0); // No Clustering
                jCBUserSimulation.setSelectedIndex(2); // Random
                jCBRelationalData.setSelectedIndex(0); // No Relational Data
                break;
            default:
                break;
        }
    }//GEN-LAST:event_jCBPresetActionPerformed

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new NewJFrame().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton3;
    private javax.swing.JComboBox jCBClustering;
    private javax.swing.JComboBox jCBDataSet;
    private javax.swing.JComboBox jCBLayout;
    private javax.swing.JComboBox jCBPreset;
    private javax.swing.JComboBox jCBRelationalData;
    private javax.swing.JCheckBox jCBRestart;
    private javax.swing.JComboBox jCBUserSimulation;
    private javax.swing.JCheckBox jCheckBox1;
    private javax.swing.JCheckBox jCheckBox2;
    private javax.swing.JCheckBox jCheckBox3;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel12;
    private javax.swing.JLabel jLabel13;
    private javax.swing.JLabel jLabel14;
    private javax.swing.JLabel jLabel15;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JMenu jMenu1;
    private javax.swing.JMenu jMenu2;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JSpinner jSNumRuns;
    private javax.swing.JSplitPane jSplitPane1;
    private javax.swing.JSplitPane jSplitPane2;
    private javax.swing.JTextField jTFCurrentRun;
    private javax.swing.JTextField jTFNumNodesMoved;
    private javax.swing.JTextField jTFPercARI;
    private javax.swing.JTextField jTFPercNodesMoved;
    private javax.swing.JTabbedPane jTabbedPane1;
    private javax.swing.JTabbedPane jTabbedPane2;
    private javax.swing.JTextField jTextField1;
    // End of variables declaration//GEN-END:variables

}
